#ifndef _FNT_VIEWER_H_
#define _FNT_VIEWER_H_

#include <QOpenGLWidget>

class Session;
class Position;
class Options;
struct Cube;
class Graph;
class OptionsPage;
class EdgePriv;
class Path;

struct ViewerShared;

struct ViewerPriv;
class Viewer : public QOpenGLWidget {
	Q_OBJECT;
	friend struct ViewerPriv;
	ViewerPriv*const priv;
	//
	void initializeGL() override;
	void paintGL() override;
	void resizeGL(int w, int h) override;
	void dropEvent(QDropEvent* drop) override;
	void dragEnterEvent(QDragEnterEvent* drop) override;

	public Q_SLOTS:
		void setSliceMode(bool checked);
		void setEdgeVisibility(bool checked);

	public:
	Viewer(Session* s);
	~Viewer();

	static ViewerShared* createShared();
	static void destroyShared(ViewerShared* viewerShared);

	void setSession(Options* options, Graph gr, const std::array<Cube, 9>& cubes, const std::array<std::pair<double, double>, 9>& xfuncs, const std::array<double, 6>& bbox, double mvol);

	void setProgressData(const std::vector<int32_t>& dat);
	void setPathData(const Path& pth);

	void wheelEvent(QWheelEvent* event) override;
	void mousePressEvent(QMouseEvent* ev) override;
	void mouseMoveEvent(QMouseEvent* ev) override;
	void mouseReleaseEvent(QMouseEvent* ev) override;

	bool clearSelection();
	void updateCube(int ch, const Cube& cube, const std::pair<double, double>& xfunc);
	void updateBoundingBox(const std::array<double, 6>& bbox);
	void updateXfunc(int ch, const std::pair<double, double>& cube);

	void updatePosition(const Position& p, bool cur);
	void updateEdgeNode(EdgePriv* ep, size_t edgPos);
	void updateEdge(EdgePriv* ep);
	void recycleEdge(EdgePriv* ep);
	void saveOptions(Options* opt) const;

	void attachOptionsDlg();
	void detachOptionsDlg();

	QImage takeScreenshot();
	void toggleRotate();
};

#endif
